import {Injectable} from '@nestjs/common';
// ORM
import {InjectRepository} from '@nestjs/typeorm';
import {Repository, UpdateResult} from 'typeorm';
import {UserListEntity} from '../entity/user.list.entity';
import {UserListDto} from '../dto/user.list.dto';
import {UserStatus} from "../common/constants";
import Decimal from "decimal.js";

@Injectable()
export class UserListService {
    constructor(
        @InjectRepository(UserListEntity)
        private readonly userRepository: Repository<UserListEntity>,
    ) {
    }

    async createOne(userListDto: UserListDto): Promise<UserListEntity> {
        return await this.userRepository.save(userListDto);
    }

    async getOneById(userId: string): Promise<UserListEntity> {
        const qb = this.userRepository.createQueryBuilder();
        qb.where({userId})
        return await qb.getOne()
    }

    async getOneByAccount(userAccount: string): Promise<UserListEntity> {
        const qb = this.userRepository.createQueryBuilder();
        qb.where({userAccount})
        return await qb.getOne()
    }

    async getOneByAccountAndPassword(userAccount: string, userPassword: string): Promise<UserListEntity> {
        const qb = this.userRepository.createQueryBuilder();
        qb.where({userAccount, userPassword})
        return await qb.getOne()
    }

    async editStatus(userId: string, status: UserStatus): Promise<UpdateResult> {
        return await this.userRepository.update({userId}, {status});
    }

    async exeRecharge(userId: string, amount: number): Promise<void> {
        return await this.userRepository.manager.transaction(async (entityManager) => {
            const user = await entityManager.findOne(UserListEntity, {
                where: {
                    userId,
                }
            })
            if (user) {
                user.balance = new Decimal(user.balance).plus(new Decimal(amount)).valueOf()
                await entityManager.save(UserListEntity, user)
            }
        })
    }

    async editPassword(userId: string, userPassword: string): Promise<UpdateResult> {
        return await this.userRepository.update({userId}, {userPassword});
    }

    async editInfo(userId: string, contact: string, remark: string): Promise<UpdateResult> {
        return await this.userRepository.update({userId}, {contact, remark});
    }
    async getAllUserListByCondition(userAccount: string, status: UserStatus, orderProp: string, order: null | "ASC" | "DESC", pageIndex: number, pageSize: number): Promise<[UserListEntity[], number]> {
        const qb = this.userRepository.createQueryBuilder('user');
        if (status) {
            qb.where({
                status
            })
        }
        if (userAccount) {
            qb.andWhere(`user.userAccount LIKE "%${userAccount}%"`)
        }
        qb.offset((pageIndex - 1) * pageSize)
            .limit(pageSize)
        if (order) {
            qb.orderBy(`user.${orderProp}`, order)
        }
        return await qb.getManyAndCount();
    }
}
